##@file
# @brief uicc package
# @author <libxiangnan@gmail.com>
# @date 2011/11/21
# @version 0.0.1
# @verbatim
# provide package sclib 0.0.1
# @endverbatim

package provide sclib 0.0.1
#@code
##@namespace sclib
# @brief namespace for developer's use.
namespace eval sclib {
	namespace export rmBlank checkAPDU parseAPDU
}

##@brief remove empty in string.
# @param[in] args input string.
# @return handled string.
# @note rmBlank a bc def =>abcdef
proc sclib::rmBlank {args} {
	variable src "" r ""
	foreach data $args {
	    append src $data
	}
	regsub -all {[ \r\t\n]+} $src "" r
	return $r
}

##@brief check apdu string legal or not.
# @param[in] apdu APDU string.
# @return A boolean flag. If legal, 1 returned, or 0 returned.
proc sclib::checkAPDU {apdu} {
	set apduLgt [string length $apdu]
	if {($apduLgt == 0) || [expr $apduLgt % 2]} {
		return 0
	}
	return [regexp {^([0-9a-fA-F]+)$} $apdu]
}

##@brief get part of a request APDU.
# @param args options(-CLA,-INS,-P1,-P2,-P3,-DATA) and request APDU.
# @return part of the request APDU.
proc sclib::parseAPDU {args} {
	variable CLA 0 INS 0 P1 0 P2 0 P3 0 DATA 0 dataLgt 0
	set argsLgt [llength $args]
	if {$argsLgt == 0} {
		return
	}
	set apdu [lindex $args [expr $argsLgt - 1]]
	set apduLgt [string length $apdu]
	if {![sclib::checkAPDU $apdu] || ($apduLgt < 10)} {
		return
	}
	scan [string range $apdu 8 9] "%02x" dataLgt
	if {$apduLgt != [expr $dataLgt*2 + 10]} {
		return
	} else {
		for {set i 0} {$i < [expr [llength $args] - 1]} {incr i} {
			set el [lindex $args $i]
			switch -nocase $el {
				-CLA {set CLA 1}
				-INS {set INS 1}
				-P1 {set P1 1}
				-P2 {set P2 1}
				-P3 {set P3 1}
				-DATA {set DATA 1}
			}
		}
		if {$CLA} { set r [string range $apdu 0 1] }
		if {$INS} { append r [string range $apdu 2 3] }
		if {$P1} { append r [string range $apdu 4 5] }
		if {$P2} { append r [string range $apdu 6 7] }
		if {$P3} { append r [string range $apdu 8 9] }
		if {$DATA} { append r [string range $apdu 10 end] }
		return $r
	}
}